﻿#include "widget.h"

#include <QDebug>
#include <QMetaType>
#include <QTimer>
#include <QVector>

#include "./ui_widget.h"

#include <libdaq/device/DAQ331M/daq_331_m.h>

using namespace libdaq::device;

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {
  ui->setupUi(this);
  // 注册
  qRegisterMetaType<QVector<QVector<double>>>("QVector<QVector<double>>");

  for (int var = 0; var < 8; ++var) {
    ui->widget->addGraph();
    ui->widget->graph(var)->setPen(channel_color_list_[var]);
  }

  ui->widget->xAxis->setRange(0, 1000);
  ui->widget->yAxis->setRange(-5, 5);
  ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom |
                              QCP::iSelectAxes);

  timer_ = new QTimer();
  connect(timer_, &QTimer::timeout, this, &Widget::ProcessData);
}

Widget::~Widget() { delete ui; }

void Widget::ProcessData() {
  auto enable_channel_size = daq331m.GetADCEnableChannelSize();
  auto storage_depth = daq331m.GetCurrentSampleRate() / enable_channel_size;
  auto legal_channel_size = daq331m.GetADCLegalChannelSize();
  QVector<QVector<double>> receive_data(legal_channel_size);
  for (int var = 0; var < receive_data.size(); ++var) {
    receive_data[var].resize(storage_depth);
  }

  // 判断当前数据是否已经满足读取的条件
  if (!daq331m.ADCDataIsReady(storage_depth)) {
    return;
  }

  auto read_result = true;
  for (int channel = 0; channel < legal_channel_size; channel++) {

    // 判断通道是否开启
    if (!(channel_state & (1 << channel))) {
        continue;
    }

    // 读取数据
    read_result = daq331m.TryReadADCData(channel, receive_data[channel].data(),
                                         receive_data[channel].size(), 1000);

    if (!read_result) {
      qDebug() << "Error";
    }
  }

  QVector<double> x_data(storage_depth);
  for (int var = 0; var < storage_depth; ++var) {
    x_data[var] = 1000.0 / storage_depth * var;
  }

  if (read_result) {
    for (int var = 0; var < legal_channel_size; ++var) {
      ui->widget->graph(var)->setData(x_data, receive_data[var]);
    }
    ui->widget->replot(QCustomPlot::rpQueuedReplot);
  }
}

void Widget::on_ConnectPushButton_clicked() {
#if defined(USE_RS485) && !defined(USE_TCP_CLIENT) && !defined(USE_MODBUS)
  daq331m.UseSerialBackend(R"(\\.\COM20)", 115200);
#elif defined(USE_TCP_CLIENT) && !defined(USE_RS485) && !defined(USE_MODBUS)
  daq331m.UseTCPClientBackend("192.168.1.100", 8000);
#elif defined(USE_MODBUS) && !defined(USE_RS485) && !defined(USE_TCP_CLIENT)
  daq331m.UseModbusRTUBackend(R"(\\.\COM20)", 115200, 1);
#endif

  // 初始化一个DAQ设备
  if (!daq331m.InitializeDevice()) {
    qDebug() << (u8"libdaq初始化设备失败");
  }

  // 连接一个DAQ设备
  if (!daq331m.ConnectedDevice()) {
    qDebug(u8"libdaq连接设备失败");
  }

  // TCP模式下最大可以配置采样率为100k，电压为15V
  // 串口模式下最大可以配置采样率为500，电压为15V
  // Modbus模式下最大可以配置采样率为80，电压为15V
  auto voltage_range = DAQVoltage::Voltage15V;
  auto sample_rate = DAQADCSampleRate::SampleRate1K;
#if defined(USE_RS485) && !defined(USE_TCP_CLIENT) && !defined(USE_MODBUS)
  sample_rate = DAQADCSampleRate::SampleRate1K;
#elif defined(USE_TCP_CLIENT) && !defined(USE_RS485) && !defined(USE_MODBUS)
  sample_rate = DAQADCSampleRate::SampleRate100K;
#elif defined(USE_MODBUS) && !defined(USE_RS485) && !defined(USE_TCP_CLIENT)
  sample_rate = DAQADCSampleRate::SampleRate80;
#endif
  if (!daq331m.ConfigureADCParameters(sample_rate, voltage_range)) {
    qDebug(u8"配置DAQ331M采样率与电压失败");
  }
  channel_state = 0b11111111; // 修改通道
  if (!daq331m.ConfigADCChannel(channel_state)) {
    qDebug(u8"配置DAQ331M通道失败");
  }
}

void Widget::on_StartPushButton_clicked() {
  timer_->setInterval(900);
  timer_->start();
  if (daq331m.StartADCCollection()) {
    qDebug() << u8"DAQ331M开始采集数据";
  }
}

void Widget::on_StopPushButton_clicked() {
  // 停止采集
  if (daq331m.StopADCCollection()) {
    qDebug() << u8"DAQ331M停止采集数据";
  }
  timer_->stop();
}
